/*
 * edulisp_lextable.hpp
 *
 *  Created on: 13.04.2011
 *      Author: Lufterd
 */

#ifndef EDULISP_LEXTABLE_HPP_
#define EDULISP_LEXTABLE_HPP_

#include "edulisp.hpp"
#include <vector>
#include <list>
#include <iostream>
#include <sstream>
#include <map>
//Локальные инклады

using namespace std;

enum LexemeType { LT_ID, LT_OP, LT_CONST, LT_RESULT, LT_RESULT_PASS };
enum DataType { DT_INT, DT_STRING, DT_DOUBLE, DT_USERFUNCTION, DT_NULL };

class NameTable_Entry;

//Класс карты локальных переменных
class LocalVariables : public map<Lexeme, NameTable_Entry*>
{
public:
	~LocalVariables();
};

//Элемент карты локальных переменных
typedef pair<Lexeme, NameTable_Entry*> LocalVariable;

//Класс таблицы имён
class NameTable : public vector<NameTable_Entry*>
{
public:
	~NameTable();
	//Поиск индекса элемента в таблице имён по имени
	int NameIndex(string& Name, int Owner_ = -1);
	//int OwnerIndex(NameTable& vNameTable, NameTable_Entry& Entry);
	//Поиск индекса элемента в тиблице имён по строковому содержимому
	int StringValueIndex(string& StringValue);
};

//Список аргументов для дескриптора функции
typedef list<Lexeme> ArgumentDescriptor;

//Класс дескриптора функции
class FunctionDescriptor
{
private:
	ArgumentDescriptor *pArguments;
	LexemeList Lexemes;
	Lexeme FunctionID_;
	LocalVariables LocalVariables_;
public:
	FunctionDescriptor(Lexeme FunctionID = -1);
	FunctionDescriptor(const FunctionDescriptor& obj);
	~FunctionDescriptor();
	ArgumentDescriptor* CreateArgumentList();
	ArgumentDescriptor* GetArgumentList();
	LexemeList& GetLexemeList();
	Lexeme GetFunctionID();
	void CheckAndAddLocalVariable(Lexeme, NameTable& NameTable_);
	void SetFunctionID(Lexeme FunctionID);
	LocalVariables& GetLocalVariables();
protected:
};

//Класс универсального объекта интерпретатора
class NameTable_Entry {
public:
    NameTable_Entry(string*, LexemeType, int Value);
    NameTable_Entry(LexemeType, string& Value);
    NameTable_Entry(string*, LexemeType, double Value);
    NameTable_Entry(string*, LexemeType);
    NameTable_Entry(string*, int = -1);
    NameTable_Entry(const NameTable_Entry& other);
    bool operator==(NameTable_Entry& obj);
    ~NameTable_Entry();

    string *GetString();
    int *GetInteger();
    double *GetFloat();
    FunctionDescriptor* GetFunctionDescriptor();

    DataType GetDataType();
    LexemeType GetLexemeType();
    string* GetText();
    int GetOwner();

    void CopyData(const NameTable_Entry& other, bool NewEntry = false);
    void SetLexemeType(LexemeType LexemeType_);
    bool ZeroValue();

    void SetData(int Value);
    void SetData(string& Value);
    void SetData(double Value);
    FunctionDescriptor* CreateFunctionDescriptor();
private:
    void DeleteData();
    LexemeType eLexemeType_;
    DataType eDataType;
    string *pText;
    void *Value_;
    int Owner;
};

ostream& operator<<(ostream& stream, NameTable_Entry& obj);
istream& operator>>(istream& stream, NameTable_Entry& obj);

#endif // EDULISP_LEXTABLE_HPP_ INCLUDED
